<?php
/******************************************************************************************
 * The contents of this file are subject to the SOURCE CODE AGREEMENT ("License Agreement")
 * which can be viewed at http://www.letrium.com/jetmobile-agreement
 *
 * BY DOWNLOADING AND/OR INSTALLING AND/OR USING THIS FILE YOU AGREE TO BE BOUND BY THE TERMS
 * OF THIS LICENSE AGREEMENT. IF YOU DO NOT AGREE TO THE TERMS OF THIS LICENSE AGREEMENT,
 * PLEASE DO NOT DOWNLOAD, INSTALL, RUN, OR OTHERWISE USE THE SOURCES OF THE SOFTWARE.
 * Under the terms of the license, You shall not, among other things:
 * 1) permit, authorize, license or sublicense any third party to view or use
 * the Source Code; 2) sell, rent, lease, distribute, make available, publish or
 * otherwise transfer the Source Code; 3) develop Forked Software;
 * 4) use the Source Code for anything other than its intended, legitimate,
 * and legal purpose.
 *
 * You do not have the right to remove Letrium copyrights from the source code
 * or user interface.
 *
 * To the maximum extent permitted by applicable law, Letrium shall not be liable
 * to Licensee for any incidental, consequential, special, punitive or
 * indirect damages, including without limitation, damages for loss of profits,
 * business opportunity, data or use, incurred by Licensee or any third party,
 * even if it has been advised of the possibility of such damages.
 * Letrium makes no representations or warranties with respect to the Source Code.
 * All express or implied representations and warranties, including without
 * limitation any implied warranty of merchantability, of fitness for a particular
 * purpose, of reliability or availability, of accuracy or completeness of responses,
 * of results, of workmanlike effort, of lack of viruses, and of lack of negligence,
 * is hereby expressly disclaimed. Licensee specifically acknowledges that the Source Code
 * is provided "as is" and may have bugs, errors, defects or deficiencies.
 *
 * Copyright (C) 2012 Letrium ltd.; All Rights Reserved.
 ******************************************************************************************/

require_once('service/v4/SugarWebServiceImplv4.php');
require_once('service/jetMobile/SugarWebServiceUtiljetMobile.php');

class SugarWebServiceImpljetMobile extends SugarWebServiceImplv4
{

    /**
     * Class Constructor Object
     *
     */
    public function __construct()
    {
        self::$helperObject = new SugarWebServiceUtiljetMobile();
    }
    
    public function getRelatedCount($session, $moduleName, $moduleId, $linkFieldName)
    {    
        if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', $module_name, 'read', 'no_access', $error)) {
            $GLOBALS['log']->error('End: SugarWebServiceImpl->get_entry_list - FAILED on checkSessionAndModuleAccess');
            return;
        }
        
        $count = 0;	
    	$bean = BeanFactory::getBean($moduleName, $moduleId);
    	if ($bean) {
			$bean->load_relationship($linkFieldName);
			$qu = $this->getRelatedQuery($bean, $linkFieldName);
			$re = $GLOBALS['db']->query($qu);
			while ($ro = $GLOBALS['db']->fetchByAssoc($re)) {
				$count++;
			}
		}
    	return $count;    	
    }
    
    protected function getRelatedQuery($bean, $link, $orderBy = 'id')
    {
    		$relatedModule = $bean->$link->getRelatedModuleName();
    		$tableName = $bean->$link->getRelatedTableName();
    		
		    $ownerWhere = "";
		    $relBean = BeanFactory::getBean($relatedModule);
       		if ($relBean->bean_implements('ACL') && ACLController::requireOwner($relBean->module_dir, 'list')) {
       			$ownerWhere = " AND " . $relBean->getOwnerWhere($GLOBALS['current_user']->id) . " ";
       		}
			
			$params = $bean->$link->getJoin(array(), true);
			if ($params['type'] == 'many-to-many') {
				$qu = "
					SELECT {$tableName}.id FROM {$bean->$link->getRelatedTableName()}
					{$bean->$link->getSubpanelQuery()} 
					WHERE {$tableName}.deleted = 0 {$ownerWhere}
					ORDER BY {$tableName}.{$orderBy}
				";
			} else {
				$qu = $bean->$link->getQuery() . " AND {$tableName}.deleted = 0 {$ownerWhere}
					ORDER BY {$tableName}.{$orderBy}
				";
			}

			return $qu;
    }
    
    public function getRelatedEntries($session, $moduleName, $moduleId, $linkFieldName, $orderBy = 'date_entered DESC', $offset = 0, $limit = 10)
    {
        $error = new SoapError();
		if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', $moduleName, 'read', 'no_access', $error)) {
		    $GLOBALS['log']->error('End: SugarWebServiceImpl->get_entry_list - FAILED on checkSessionAndModuleAccess');
		    return;
		}
        
		$module = $moduleName;
		$id = $moduleId;
		$link = $linkFieldName;

		$bean = BeanFactory::getBean($module, $id);
		
		$entryList = array();
		
        require_once "include/SugarDateTime.php";
       	$tzName = $GLOBALS['current_user']->getPreference('timezone');
       	if (empty($tzName)) {
       		$tzName = 'UTC';
       	}
		$userTimeZone = new DateTimeZone($tzName);	
		
		if ($bean) {
			$bean->load_relationship($link);			
			
			$relatedModule = $bean->$link->getRelatedModuleName();
			$tableName = $bean->$link->getRelatedTableName();
			
		    if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', $relatedModule, 'read', 'no_access', $error)) {
		        $GLOBALS['log']->error('End: SugarWebServiceImpl->get_entry_list - FAILED on checkSessionAndModuleAccess');
		        return;
		    }
		    
			$qu = $this->getRelatedQuery($bean, $link, $orderBy);			
			$re = $GLOBALS['db']->limitQuery($qu, $offset, $limit);
		
			
			$resultCount = 0;
			while ($ro = $GLOBALS['db']->fetchByAssoc($re)) {
				$relatedBean = BeanFactory::getBean($relatedModule, $ro['id']);
			
				$list = array();
				foreach ($relatedBean->field_defs as $field => $defs) {
					$list[$field] = array(
						'name' => $field,
						'value' => $relatedBean->$field,
					);
				}
			
				$entryList[] = array(
					'id' => $relatedBean->id,
					'module_name' => $relatedBean->module_name, 
					'name_value_list' => $list
				);
				$resultCount ++;					
			}
		}
		
		foreach ($entryList as $i => $v) {
			foreach ($entryList[$i]['name_value_list'] as $fieldName => $w) {
		        if ($relatedBean->field_defs[$fieldName]['type'] == 'datetimecombo') {  
		        	$value = $entryList[$i]['name_value_list'][$fieldName]['value'];
		        	$dateTime = SugarDateTime::createFromFormat('Y-m-d H:i:s', $value, new DateTimeZone('UTC'));
		        	if ($dateTime) {
				    	$dateTime->setTimeZone($userTimeZone);
				   		$value = $dateTime->format('Y-m-d H:i:s');
		       		}
		       		$entryList[$i]['name_value_list'][$fieldName]['value'] = $value;
		        }
			}
		}
		
		return array(
			'entry_list' => $entryList,
			'next_offset' => 0,
			'relationship_list' => array(),
			'result_count' => $resultCount,
			'total_count' => $this->getRelatedCount($session, $moduleName, $moduleId, $linkFieldName),
			'parentName' => $bean->name		
		);		
    }
    
    protected function _login($user_auth, $application, $name_value_list = array()){
    
        $GLOBALS['log']->info("Begin: SugarWebServiceImpl->login({$user_auth['user_name']}, $application, ". print_r($name_value_list, true) .")");
        global $sugar_config, $system_config;
        $error = new SoapError();
        $user = new User();
        $success = false;
        //rrs
        $system_config = new Administration();
        $system_config->retrieveSettings('system');
        $authController = new AuthenticationController((!empty($sugar_config['authenticationClass'])? $sugar_config['authenticationClass'] : 'SugarAuthenticate'));
        //rrs
        if(!empty($user_auth['encryption']) && $user_auth['encryption'] === 'PLAIN' && $authController->authController->userAuthenticateClass != "LDAPAuthenticateUser")
        {
            $user_auth['password'] = md5($user_auth['password']);
        }
        
        $isLoginSuccess = $authController->login($user_auth['user_name'], $user_auth['password'], array('passwordEncrypted' => false));
        
        
        $usr_id=$user->retrieve_user_id($user_auth['user_name']);
        if($usr_id)
            $user->retrieve($usr_id);

        if ($isLoginSuccess)
        {
            if ($_SESSION['hasExpiredPassword'] =='1')
            {
                $error->set_error('password_expired');
                $GLOBALS['log']->fatal('password expired for user ' . $user_auth['user_name']);
                LogicHook::initialize();
                $GLOBALS['logic_hook']->call_custom_logic('Users', 'login_failed');
                self::$helperObject->setFaultObject($error);
                return;
            }
            if(!empty($user) && !empty($user->id) && !$user->is_group)
            {
                $success = true;
                global $current_user;
                $current_user = $user;
            }
        }
        else if($usr_id && isset($user->user_name) && ($user->getPreference('lockout') == '1'))
        {
            $error->set_error('lockout_reached');
            $GLOBALS['log']->fatal('Lockout reached for user ' . $user_auth['user_name']);
            LogicHook::initialize();
            $GLOBALS['logic_hook']->call_custom_logic('Users', 'login_failed');
            self::$helperObject->setFaultObject($error);
            return;
        }
		else if(function_exists('mcrypt_cbc') && $authController->authController->userAuthenticateClass == "LDAPAuthenticateUser"
        		&& (empty($user_auth['encryption']) || $user_auth['encryption'] !== 'PLAIN' ) )
        {
            $password = self::$helperObject->decrypt_string($user_auth['password']);
            $authController->loggedIn = false; // reset login attempt to try again with decrypted password
            if($authController->login($user_auth['user_name'], $password) && isset($_SESSION['authenticated_user_id']))
                $success = true;
        }
        else if( $authController->authController->userAuthenticateClass == "LDAPAuthenticateUser"
                 && (empty($user_auth['encryption']) || $user_auth['encryption'] == 'PLAIN' ) )
        {

        	$authController->loggedIn = false; // reset login attempt to try again with md5 password
        	if($authController->login($user_auth['user_name'], md5($user_auth['password']), array('passwordEncrypted' => true))
        		&& isset($_SESSION['authenticated_user_id']))
        	{
        		$success = true;
        	}
        	else
        	{

	            $error->set_error('ldap_error');
	            LogicHook::initialize();
	            $GLOBALS['logic_hook']->call_custom_logic('Users', 'login_failed');
	            self::$helperObject->setFaultObject($error);
	            return;
        	}
        }

        if($success)
        {
            session_start();
            global $current_user;
            //$current_user = $user;
            self::$helperObject->login_success($name_value_list);
            $current_user->loadPreferences();
            $_SESSION['is_valid_session']= true;
            $_SESSION['ip_address'] = query_client_ip();
            $_SESSION['user_id'] = $current_user->id;
            $_SESSION['type'] = 'user';
            $_SESSION['avail_modules']= self::$helperObject->get_user_module_list($current_user);
            $_SESSION['authenticated_user_id'] = $current_user->id;
            $_SESSION['unique_key'] = $sugar_config['unique_key'];
            $GLOBALS['log']->info('End: SugarWebServiceImpl->login - successful login');
            $current_user->call_custom_logic('after_login');
            $nameValueArray = array();
            global $current_language;
            $nameValueArray['user_id'] = self::$helperObject->get_name_value('user_id', $current_user->id);
            $nameValueArray['user_name'] = self::$helperObject->get_name_value('user_name', $current_user->user_name);
            $nameValueArray['user_language'] = self::$helperObject->get_name_value('user_language', $current_language);
            $cur_id = $current_user->getPreference('currency');
            $nameValueArray['user_currency_id'] = self::$helperObject->get_name_value('user_currency_id', $cur_id);
            $nameValueArray['user_is_admin'] = self::$helperObject->get_name_value('user_is_admin', is_admin($current_user));
            $nameValueArray['user_default_team_id'] = self::$helperObject->get_name_value('user_default_team_id', $current_user->default_team );
            $nameValueArray['user_default_dateformat'] = self::$helperObject->get_name_value('user_default_dateformat', $current_user->getPreference('datef') );
            $nameValueArray['user_default_timeformat'] = self::$helperObject->get_name_value('user_default_timeformat', $current_user->getPreference('timef') );

            $num_grp_sep = $current_user->getPreference('num_grp_sep');
            $dec_sep = $current_user->getPreference('dec_sep');
            $nameValueArray['user_number_seperator'] = self::$helperObject->get_name_value('user_number_seperator', empty($num_grp_sep) ? $sugar_config['default_number_grouping_seperator'] : $num_grp_sep);
            $nameValueArray['user_decimal_seperator'] = self::$helperObject->get_name_value('user_decimal_seperator', empty($dec_sep) ? $sugar_config['default_decimal_seperator'] : $dec_sep);

            $nameValueArray['mobile_max_list_entries'] = self::$helperObject->get_name_value('mobile_max_list_entries', $sugar_config['wl_list_max_entries_per_page'] );
            $nameValueArray['mobile_max_subpanel_entries'] = self::$helperObject->get_name_value('mobile_max_subpanel_entries', $sugar_config['wl_list_max_entries_per_subpanel'] );


            $currencyObject = new Currency();
            $currencyObject->retrieve($cur_id);
            $nameValueArray['user_currency_name'] = self::$helperObject->get_name_value('user_currency_name', $currencyObject->name);
            $_SESSION['user_language'] = $current_language;
            return array('id'=>session_id(), 'module_name'=>'Users', 'name_value_list'=>$nameValueArray);
        }
        LogicHook::initialize();
        $GLOBALS['logic_hook']->call_custom_logic('Users', 'login_failed');
        $error->set_error('invalid_login');
        self::$helperObject->setFaultObject($error);
        $GLOBALS['log']->error('End: SugarWebServiceImpl->login - failed login');
    }
    
    
    public function login($user_auth, $application = '', $name_value_list = array())
    {
    	$output = $this->_login($user_auth, $application = '', $name_value_list);
    	if (isset($output['name_value_list']['user_id']['value'])) {
			$locale = new Localization();
			
			$GLOBALS['current_user']->reloadPreferences();
			
			require_once "include/TimeDate.php";
			$timeDate = new TimeDate($GLOBALS['current_user']);
			$GLOBALS['disable_date_format'] = false;
    		$output['timeZoneOffset'] = $timeDate->getUserUTCOffset($GLOBALS['current_user']);
    		$output['dateFormat'] = $locale->getPrecedentPreference('datef', $GLOBALS['current_user']);
    		$output['timeFormat'] = $locale->getPrecedentPreference('timef', $GLOBALS['current_user']);
    		
    		$output['languageList'] = get_languages();
    		
    		
    		$output['flav'] = 'lite';
    		
    		
    		
  		
    		$moduleList = explode(";", SugarConfig::getInstance()->get("mobile_settings.modules"));
    		
    		$modelList = array();
    		foreach ($moduleList as $moduleName) {
    		
    			if (!ACLController::checkAccess($moduleName, 'list', true)) {
    				continue;
    			}
    			$singular = false;
    			if (isset($GLOBALS['beanList'][$moduleName])) {
    				$singular = $GLOBALS['beanList'][$moduleName];
    			}
    			$plural = $moduleName;    			
    			if ($singular == $plural) {
    				$plural .= "Collection";
    			}    			 
    			$modelList[$moduleName] = array(
    				'singular' => $singular,
    				'plural' => $plural
    			);
    		}    		 
    		$output['modelList'] = $modelList;
    		
    	};
    	return $output;
    }
    
    /**
     * Update or create a single SugarBean.
     *
     * @param String $session -- Session ID returned by a previous call to login.
     * @param String $module_name -- The name of the module to return records from.  This name should be the name the module was developed under (changing a tab name is studio does not affect the name that should be passed into this method)..
     * @param Array $name_value_list -- The keys of the array are the SugarBean attributes, the values of the array are the values the attributes should have.
     * @param Bool $track_view -- Should the tracker be notified that the action was performed on the bean.
     * @return Array    'id' -- the ID of the bean that was written to (-1 on error)
     * @exception 'SoapFault' -- The SOAP error, if any
     */
    function set_entry($session,$module_name, $name_value_list, $track_view = FALSE)
    {
        global  $beanList, $beanFiles, $current_user;
        
        $locale = new Localization();        
  


        $GLOBALS['log']->info('Begin: SugarWebServiceImpl->set_entry');
        if (self::$helperObject->isLogLevelDebug()) {
            $GLOBALS['log']->debug('SoapHelperWebServices->set_entry - input data is ' . var_export($name_value_list, true));
        } // if
        $error = new SoapError();
        if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', $module_name, 'write', 'no_access', $error)) {
            $GLOBALS['log']->info('End: SugarWebServiceImpl->set_entry');
            return;
        } // if
        
        require_once "include/SugarDateTime.php";
       	$tzName = $GLOBALS['current_user']->getPreference('timezone');
       	if (empty($tzName)) {
       		$tzName = 'UTC';
       	}
		$userTimeZone = new DateTimeZone($tzName);        
        
        $class_name = $beanList[$module_name];
        require_once($beanFiles[$class_name]);
        $seed = new $class_name();
        foreach($name_value_list as $name=>$value){
            if(is_array($value) &&  $value['name'] == 'id'){
                $seed->retrieve($value['value']);
                break;
            }else if($name === 'id' ){

                $seed->retrieve($value);
            }
        }
		
		$valueHash = array();
        
        $return_fields = array();
        foreach($name_value_list as $name=>$value){
            if($module_name == 'Users' && !empty($seed->id) && ($seed->id != $current_user->id) && $name == 'user_hash'){
                continue;
            }
            if(!empty($seed->field_name_map[$name]['sensitive'])) {
                    continue;
            }
                        
            
            if(!is_array($value)){
                $seed->$name = $value;
                $return_fields[] = $name;
                $valueHash[$name] = $value;
                $fieldName = $name; 
            }else{
            	$valueHash[$value['name']] = $value['value'];
                $seed->$value['name'] = $value['value'];
                $return_fields[] = $value['name'];
                $fieldName = $value['name'];
            }
            
            if ($seed->field_defs[$fieldName]['type'] == 'datetimecombo') {            
            	$dateTime = SugarDateTime::createFromFormat('Y-m-d H:i:s', $seed->$fieldName, $userTimeZone);
            	if ($dateTime) {
            		$dateTime->setTimeZone(new DateTimeZone('UTC'));
           			$seed->$fieldName = $dateTime->format('Y-m-d H:i:s');
           		}
            }
        }
        if (!self::$helperObject->checkACLAccess($seed, 'Save', $error, 'no_access') || ($seed->deleted == 1  && !self::$helperObject->checkACLAccess($seed, 'Delete', $error, 'no_access'))) {
            $GLOBALS['log']->info('End: SugarWebServiceImpl->set_entry');
            return;
        } // if
		
		// letrium v
		$moduleCheckDuplicate = array('Accounts', 'Contacts', 'Leads');
		// Bug.
		// existing record not updated. Add && empty($seed->id)
		if (in_array($module_name, $moduleCheckDuplicate) && empty($seed->id)) {
			$ignoreDuplicate = false;
			foreach($name_value_list as $name=>$value){
		        if($name === 'ignore_duplicate' && $value['value'] ) {
		           	$ignoreDuplicate = true;
		           	break;
		        }
		    }
		    if (!$ignoreDuplicate) {
		    	$query = '';
		    	switch ($module_name) {
		    		case 'Accounts':
		    			$baseQuery = 'select id, name, website, billing_address_city  from accounts where deleted!=1 and ';
						if ( !empty($name_value_list['name']) && !empty($name_value_list['name']['value']) ) {
							$query = $baseQuery ."  name like '".$name_value_list['name']['value']."%'";
						}

						if ( (!empty($name_value_list['billing_address_city']) && !empty($name_value_list['billing_address_city']['value'])) || (!empty($name_value_list['shipping_address_city']) && !empty($name_value_list['shipping_address_city']['value'])) ) {

							$temp_query = '';
							if ( !empty($name_value_list['billing_address_city']) && !empty($name_value_list['billing_address_city']['value']) ){
								if (empty($temp_query)) {
									$temp_query =  "  billing_address_city like '".$name_value_list['billing_address_city']['value']."%'";
								}
								else {
									$temp_query .= "or billing_address_city like '".$name_value_list['billing_address_city']['value']."%'";
								}
							}
							if ( !empty($name_value_list['shipping_address_city']) && !empty($name_value_list['shipping_address_city']['value']) ) {
								if (empty($temp_query)) {
									$temp_query = "  shipping_address_city like '".$name_value_list['shipping_address_city']['value']."%'";
								}
								else {
									$temp_query .= "or shipping_address_city like '".$name_value_list['shipping_address_city']['value']."%'";
								}
							}
							if (empty($query)) {
								$query .= $baseQuery;
							}
							else{
								$query .= ' AND ';
							}
							$query .=   ' ('. $temp_query . ' ) ';
						}
		    			break;
		    			
		    		case 'Contacts':
		    			$query = 'SELECT contacts.id, contacts.first_name, contacts.last_name, contacts.title FROM contacts ';
						$query .= ' where contacts.deleted = 0 AND ';
						if (isset($name_value_list['first_name']) && isset($name_value_list['first_name']['value']) && strlen($name_value_list['first_name']['value']) != 0 && isset($name_value_list['last_name']) && isset($name_value_list['last_name']['value']) && strlen($name_value_list['last_name']['value']) != 0) {
							$query .= " contacts.first_name LIKE '". $name_value_list['first_name']['value'] . "%' AND contacts.last_name = '". $name_value_list['last_name']['value'] ."'";
						}
						else {
							$query .= " contacts.last_name = '". $name_value_list['last_name']['value'] ."'";
						}

						if (!empty($name_value_list['record']) && !empty($name_value_list['record']['value'])) {
							$query .= " AND  contacts.id != '". $name_value_list['record']['value'] ."'";
						}
		    			break;
		    			
		    		case 'Leads':
		    			$query = "SELECT id, first_name, last_name, account_name, title FROM leads ";
						$query .= " WHERE deleted != 1 AND (status <> 'Converted' OR status IS NULL) AND ";
						if (isset($name_value_list['first_name']) && isset($name_value_list['first_name']['value']) && strlen($name_value_list['first_name']['value']) != 0 && isset($name_value_list['last_name']) && isset($name_value_list['last_name']['value']) && strlen($name_value_list['last_name']['value']) != 0) {
							$query .= " (first_name='". $name_value_list['first_name']['value'] . "' AND last_name = '". $name_value_list['last_name']['value'] ."')";
						}
						else {
							$query .= " last_name = '". $name_value_list['last_name']['value'] ."'";
						}
		    			break;
		    	}
		    	
		    	// check for duplicate
		    	$foundDuplicate = false;
		    	if (!empty($query)) {
					global $db;
					$result = $db->query($query);
					if ($row = $db->fetchByAssoc($result)) {
						$foundDuplicate = true;
					}
				}
				
				if ($module_name != 'Accounts') {
					//Now check for duplicates using email values supplied
					$count = 1;
					$emailStr = '';
					while(isset($name_value_list["email{$count}"]) && isset($name_value_list["email{$count}"]['value']))
					{
						  $emailStr .= ",'" . strtoupper(trim($name_value_list["email" . $count++]['value'])) . "'";
					} //while

					if(!empty($emailStr))
					{
						$emailStr = substr($emailStr, 1);
						$query = 'SELECT DISTINCT er.bean_id AS id FROM email_addr_bean_rel er, ' .
								 'email_addresses ea WHERE ea.id = er.email_address_id ' .
								 'AND ea.deleted = 0 AND er.deleted = 0 AND er.bean_module = \'' . $module_name . '\' ' .
								 'AND email_address_caps IN (' . $emailStr . ')';

						$result = $db->query($query);
						if ($row = $db->fetchByAssoc($result)) {
							$foundDuplicate = true;
						}
					}
				}
		    	
		    	if ($foundDuplicate) {
					return array('duplicate' => true, 'id'=>'', 'entry_list' => array());
				}
		    } // if
		} // if
		// letrium v END
		
        $seed->save(self::$helperObject->checkSaveOnNotify());
        
        
        $toResave = false;
        foreach ($seed->field_defs as $fieldName => $def) {
        
        	if (!empty($valueHash[$fieldName . '_remove'])) {
        		unlink("upload://" . $seed->id);
        		$seed->$fieldName = '';
        		$toResave = true;      	
        	}
        
        	if ($def['type'] == 'file' && isset($valueHash[$fieldName]) && isset($valueHash[$fieldName . '_contents'])) {
        		$fileName = $valueHash[$fieldName];        		
        		$split = explode(",", $valueHash[$fieldName . '_contents']);
        		$contents = base64_decode($split[1]);  
        		
        		$seed->$fieldName = $fileName;
        		
		    	// letrium v
		    	if ($seed->module_dir == 'Documents'){
		    		$Revision = new DocumentRevision();
				    //save revision.
				    $Revision->in_workflow = true;
				    $Revision->not_use_rel_in_req = true;
				    $Revision->new_rel_id = $seed->id;
				    $Revision->new_rel_relname = 'Documents';
				    $Revision->change_log = translate('DEF_CREATE_LOG','Documents');
				    $Revision->revision = $seed->revision;
				    $Revision->document_id = $seed->id;
				    $Revision->filename = $seed->filename;

				    if(isset($seed->file_ext))
				    {
				    	$Revision->file_ext = $seed->file_ext;
				    }

				    if(isset($seed->file_mime_type))
				    {
				    	$Revision->file_mime_type = $seed->file_mime_type;
				    }

				    $Revision->doc_type = $seed->doc_type;
				    if ( isset($seed->doc_id) ) {
				        $Revision->doc_id = $seed->doc_id;
				    }
				    if ( isset($seed->doc_url) ) {
				        $Revision->doc_url = $seed->doc_url;
				    }

				    $Revision->id = create_guid();
				    $Revision->new_with_id = true;

				    file_put_contents("upload://".$Revision->id, $contents);
				    $Revision->save();
				    //update document with latest revision id
				    $seed->process_save_dates=false; //make sure that conversion does not happen again.
				    $seed->document_revision_id = $Revision->id;
		    		$toResave = true;
		    	}
		    	else {
		    		file_put_contents("upload://" . $seed->id, $contents); 
		    		$toResave = true;
		    	}
		    	// letrium v END   		 
        	}
        	
        }
        
        if ($toResave) {
        	$seed->save(false);
        }
        
        if (in_array($seed->module_name, array('Meetings', 'Calls'))) {
        	$seed->load_relationship('users');
        	$seed->users->add($seed->assigned_user_id);
        }

        $return_entry_list = self::$helperObject->get_name_value_list_for_fields($seed, $return_fields );
        

		foreach ($return_entry_list as $fieldName => $w) {
		        if ($seed->field_defs[$fieldName]['type'] == 'datetimecombo') {  
		        	$value = $return_entry_list[$fieldName]['value'];
		        	$dateTime = SugarDateTime::createFromFormat('Y-m-d H:i:s', $value, new DateTimeZone('UTC'));
		        	if ($dateTime) {
				    	$dateTime->setTimeZone($userTimeZone);
				   		$value = $dateTime->format('Y-m-d H:i:s');
		       		}
		       		$return_entry_list[$fieldName]['value'] = $value;
		        }
		}
		

        if($seed->deleted == 1){
            $seed->mark_deleted($seed->id);
        }

        if($track_view){
            self::$helperObject->trackView($seed, 'editview');
        }

        $GLOBALS['log']->info('End: SugarWebServiceImpl->set_entry');
        return array('id'=>$seed->id, 'entry_list' => $return_entry_list);
    }
    
    public function get_entry_list($session, $module_name, $query, $order_by,$offset, $select_fields, $link_name_to_fields_array, $max_results, $deleted, $favorites = false)
    {
		$result = parent::get_entry_list($session, $module_name, $query, $order_by,$offset, $select_fields, $link_name_to_fields_array, $max_results, $deleted, $favorites);
		
        require_once "include/SugarDateTime.php";
       	$tzName = $GLOBALS['current_user']->getPreference('timezone');
       	if (empty($tzName)) {
       		$tzName = 'UTC';
       	}
		$userTimeZone = new DateTimeZone($tzName);	
		
        $className = $GLOBALS['beanList'][$module_name];
        require_once($GLOBALS['beanFiles'][$className]);
        $seed = new $className();
		foreach ($result['entry_list'] as $i => $v) {
			foreach ($result['entry_list'][$i]['name_value_list'] as $fieldName => $w) {
		        if ($seed->field_defs[$fieldName]['type'] == 'datetimecombo') {  
		        	$value = $result['entry_list'][$i]['name_value_list'][$fieldName]['value'];
		        	$dateTime = SugarDateTime::createFromFormat('Y-m-d H:i:s', $value, new DateTimeZone('UTC'));
		        	if ($dateTime) {
				    	$dateTime->setTimeZone($userTimeZone);
				   		$value = $dateTime->format('Y-m-d H:i:s');
		       		}
		       		$result['entry_list'][$i]['name_value_list'][$fieldName]['value'] = $value;
		        }
			}
		}
		return $result;
	}
	
	public function get_calendar_entries($session, $date_from, $date_to)
	{
        $error = new SoapError();
        if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', false, false, false, $error)) {
            $GLOBALS['log']->info('End: SugarWebServiceImpl->getMobileQS');
            return;
        }
        
		require_once "include/SugarDateTime.php";
       	$tzName = $GLOBALS['current_user']->getPreference('timezone');
       	if (empty($tzName)) {
       		$tzName = 'UTC';
       	}
		$userTimeZone = new DateTimeZone($tzName);
		
		$dateFrom = SugarDateTime::createFromFormat('Y-m-d', $date_from, new DateTimeZone($tzName));
		$dateTo = SugarDateTime::createFromFormat('Y-m-d', $date_to, new DateTimeZone($tzName));
		
		require_once "modules/Calendar/CalendarActivity.php";
		$activities = CalendarActivity::get_activities($GLOBALS['current_user']->id, true, $dateFrom, $dateTo, 'week');
		
		$list = array();
		
		$resultCount = 0;
		$entryList = array();
		
		function toTz($value, $userTimeZone) {
			$dateTime = SugarDateTime::createFromFormat('Y-m-d H:i:s', $value, new DateTimeZone('UTC'));
		    if ($dateTime) {
				$dateTime->setTimeZone($userTimeZone);
				$value = $dateTime->format('Y-m-d H:i:s');
		    }
		    return $value;		    
		}
		
		
		foreach ($activities as $act) {
			$bean = $act->sugar_bean;
			$row = array(
				'moduleName' => $bean->module_name,
				'id' => $bean->id,
				'name' => $bean->name,
				'date_start' => toTz($bean->date_start, $userTimeZone),				
				'status' => $bean->status,
				'parent_type' => $bean->parent_type,				
				'parent_id' => $bean->parent_id,			
			);
			$dateField = 'date_start';
			if ($bean->module_name == 'Tasks') {
				$row['date_due'] = toTz($bean->date_due, $userTimeZone);
				$row['priority'] = $bean->priority;
				$dateField = 'date_due';
			}			

			
			$parentBean = BeanFactory::getBean($bean->parent_type, $bean->parent_id);
			$row['parent_name'] = $parentBean ? $parentBean->name : '';						
			$row['timestamp'] = SugarDateTime::createFromFormat('Y-m-d H:i:s', toTz($bean->$dateField, $userTimeZone))->ts;
			
			$list[] = $row;
			
			$resultCount ++;	
		}
		
		function compareTimestamps($a, $b) {
			if ($a['timestamp'] < $b['timestamp']) {
				return true;
			}
		}		
		
		usort($list, 'compareTimestamps');
		
		return array(
			'count' => $resultCount,
			'list' => $list,
		);
	}
	
	
	public function get_entry($session, $module_name, $id,$select_fields, $link_name_to_fields_array,$track_view = FALSE)
	{
		$result = parent::get_entry($session, $module_name, $id,$select_fields, $link_name_to_fields_array,$track_vie);
	
        require_once "include/SugarDateTime.php";
       	$tzName = $GLOBALS['current_user']->getPreference('timezone');
       	if (empty($tzName)) {
       		$tzName = 'UTC';
       	}
		$userTimeZone = new DateTimeZone($tzName);	
		
        $className = $GLOBALS['beanList'][$module_name];
        require_once($GLOBALS['beanFiles'][$className]);
        $seed = new $className();
		foreach ($result['entry_list'] as $i => $v) {
			foreach ($result['entry_list'][$i]['name_value_list'] as $fieldName => $w) {
		        if ($seed->field_defs[$fieldName]['type'] == 'datetimecombo') {  
		        	$value = $result['entry_list'][$i]['name_value_list'][$fieldName]['value'];
		        	$dateTime = SugarDateTime::createFromFormat('Y-m-d H:i:s', $value, new DateTimeZone('UTC'));
		        	if ($dateTime) {
				    	$dateTime->setTimeZone($userTimeZone);
				   		$value = $dateTime->format('Y-m-d H:i:s');
		       		}
		       		$result['entry_list'][$i]['name_value_list'][$fieldName]['value'] = $value;
		        }
			}
		}
		return $result;
	}
    
    public function getMobileQS($session, $data, $query)
    {
        $error = new SoapError();
        if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', false, false, false, $error)) {
            $GLOBALS['log']->info('End: SugarWebServiceImpl->getMobileQS');
            return;
        }
		$filePath = 'custom/jetMobile/JetMobileQuickSearch.php';
		require_once($filePath);
		$quicksearchQuery = new JetMobileQuickSearch();

		$json = getJSONobj();
		$data = $json->decode(html_entity_decode($data));
		if(isset($query) && !empty($query)){
			foreach($data['conditions'] as $k=>$v){
				if (empty($data['conditions'][$k]['value']) && ($data['conditions'][$k]['op'] != JetMobileQuickSearch::CONDITION_EQUAL)) 
				{
				    $data['conditions'][$k]['value'] = $query;
				}
			}
		}

		$method = !empty($data['method']) ? $data['method'] : 'query';
		if (method_exists($quicksearchQuery, $method)) {
			$output = $quicksearchQuery->$method($data);
			ob_clean();
			return array('data' => $output);		  
		}        
    		
    }
}
